<cfcomponent displayname="UserPreferencesDAO">

	<cfset variables.private = structNew() />

	<cffunction name="init" access="public" output="false" returntype="UserPreferencesDAO">
		<cfargument name="dsn" type="string" required="true" hint="This is the datasource to use"/>
		<cfset variables.private.dsn = arguments.dsn />
		<cfreturn this>
	</cffunction>
	
	<cffunction name="create" access="public" output="false" returntype="boolean">
		<cfargument name="User" type="User" required="true" />
		<cfset var qCreate = "" />
		<cfquery name="qCreate" datasource="#getDSN()#">
			INSERT INTO UserSettings
				(
					UserSettingID,
					UserID,
					Timezone,
					DefaultView
				)
			VALUES
				(
					<cfqueryparam value="#CreateUUID()#" CFSQLType="cf_sql_varchar" />,
					<cfqueryparam value="#arguments.User.getUserID()#" CFSQLType="cf_sql_varchar" />,
					<cfqueryparam value="#arguments.User.getTimezone()#" CFSQLType="cf_sql_varchar" />,
					<cfqueryparam value="#arguments.User.getDefaultView()#" CFSQLType="cf_sql_varchar" />
				)
		</cfquery>
		<cfreturn true />
	</cffunction>

	<cffunction name="read" access="public" output="false" returntype="void">
		<cfargument name="User" type="User" required="true" />
		<cfset var qRead = "" />
		<cfset var strReturn = structNew() />
		<cfset var preference = "" />
		<cfquery name="qRead" datasource="#getDSN()#">
			SELECT
				Timezone,
				DefaultView
			FROM	UserSettings
			WHERE	UserID = <cfqueryparam value="#arguments.User.getUserID()#" CFSQLType="cf_sql_varchar" />
		</cfquery>
		<cfif qRead.recordCount>
			<cfset strReturn = queryRowToStruct(qRead)>
			<cfloop collection="#strReturn#" item="preference">
				<cfset StructInsert(arguments.User.getMemento(), preference, strReturn[preference], true)/>
			</cfloop>
		</cfif>
	</cffunction>

	<cffunction name="update" access="public" output="false" returntype="boolean">
		<cfargument name="User" type="User" required="true" />
		<cfquery datasource="#getDSN()#">
			UPDATE	UserSettings
			SET
				Timezone = <cfqueryparam value="#arguments.User.getTimezone()#" CFSQLType="cf_sql_varchar" />,
				DefaultView = <cfqueryparam value="#arguments.User.getDefaultView()#" CFSQLType="cf_sql_varchar" />
			WHERE	UserID = <cfqueryparam value="#arguments.User.getUserID()#" CFSQLType="cf_sql_varchar" />
		</cfquery>
		<cfreturn true/>
	</cffunction>

	<cffunction name="delete" access="public" output="false" returntype="boolean">
		<cfargument name="User" type="User" required="true" />
		<cftry>
			<cfquery datasource="#getDSN()#">
			UPDATE
				UserSettings
			SET
				IsDeleted = 1
			WHERE
				UserID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.User.getUserID()#" />
			</cfquery>
			<cfcatch type="database">
				<cfreturn false />
			</cfcatch>
		</cftry>
		<cfreturn true />
	</cffunction>

	<cffunction name="exists" access="public" output="false" returntype="boolean">
		<cfargument name="User" type="User" required="true" />

		<cfset var qExists = "">
		<cfquery name="qExists" datasource="#getDSN()#" maxrows="1">
			SELECT count(1) as idexists
			FROM	UserSettings
			WHERE	UserID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.User.getUserID()#" />
		</cfquery>

		<cfif qExists.idexists>
			<cfreturn true />
		<cfelse>
			<cfreturn false />
		</cfif>
	</cffunction>

	<cffunction name="save" access="public" output="false" returntype="boolean">
		<cfargument name="User" type="User" required="true" />
		
		<cfset var success = false />
		<cfif exists(arguments.User)>
			<cfset success = update(arguments.User) />
		<cfelse>
			<cfset success = create(arguments.User) />
		</cfif>
		
		<cfreturn success />
	</cffunction>

	<cffunction name="queryRowToStruct" access="private" output="false" returntype="struct">
		<cfargument name="qry" type="query" required="true">
		
		<cfscript>
			/**
			 * Makes a row of a query into a structure.
			 * 
			 * @param query 	 The query to work with. 
			 * @param row 	 Row number to check. Defaults to row 1. 
			 * @return Returns a structure. 
			 * @author Nathan Dintenfass (nathan@changemedia.com) 
			 * @version 1, December 11, 2001 
			 */
			//by default, do this to the first row of the query
			var row = 1;
			//a var for looping
			var ii = 1;
			//the cols to loop over
			var cols = listToArray(qry.columnList);
			//the struct to return
			var stReturn = structnew();
			//if there is a second argument, use that for the row number
			if(arrayLen(arguments) GT 1)
				row = arguments[2];
			//loop over the cols and build the struct from the query row
			for(ii = 1; ii lte arraylen(cols); ii = ii + 1){
				stReturn[cols[ii]] = qry[cols[ii]][row];
			}		
			//return the struct
			return stReturn;
		</cfscript>
	</cffunction>
	
	<cffunction name="getDSN" access="public" output="false" returntype="string">
		<cfreturn variables.private.dsn />
	</cffunction>
</cfcomponent>